home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / BlitPixie / Sources / BlitPixieFlip.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  10.7 KB  |  521 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    BlitPixieFlip
  3. //            a fast horizontal-flipping blitter
  4. //
  5. //    for vertical-flipping, use normal BlitPixie with last pixel row and negative rowBytes
  6. //
  7. //    written by Anders F Björklund <afb@algonet.se>
  8. //    © 1999 afb.
  9. ///--------------------------------------------------------------------------------------
  10.  
  11. #ifndef __BLITPIXIE__
  12. #include "BlitPixieHeader.h"
  13. #endif
  14.  
  15. #include "BlitPixieAsm.h"
  16.  
  17. #pragma mark *** PowerPC asm:
  18. #if USE_PPC_ASSEMBLY
  19.  
  20. ASM_FUNC void BlitPixieFlip8Bit(
  21.     register unsigned char *source,        register unsigned char *destination,    
  22.     register unsigned long srcRowBytes,    register unsigned long dstRowBytes,
  23.     register unsigned short width,        register unsigned short height)
  24. {
  25.     #define r_srcPixel            r3
  26.     #define r_dstPixel            r4
  27.     #define r_srcOffset            r5
  28.     #define r_dstOffset            r6
  29.     #define r_width                r7
  30.     #define r_rows                r8
  31.  
  32.     #define r_words                r9
  33.     #define r_index1            r10
  34.     #define r_index2            r11
  35.     
  36.     ASM_BEGIN
  37.     
  38.     rlwinm    r_index1,r_width,0,31,31        // numBytesPerRow & 1
  39.     rlwinm    r_index2,r_width,31,31,31        // numBytesPerRow & 2
  40.     rlwinm    r_words,r_width,30,2,31            // numBytesPerRow >> 2
  41.  
  42.     cmplwi    cr7,r_index1,0
  43.     cmplwi    cr6,r_index2,0
  44.     cmplwi    cr5,r_words,0
  45.  
  46. @yloop:
  47.     
  48.     mr        r_index1,r_width
  49.     li        r_index2,0
  50.  
  51.     beq        cr5,@skipwords
  52.         mtctr    r_words
  53.     @wordloop:
  54.         subi    r_index1,r_index1,4
  55.         lwbrx    r0,r_srcPixel,r_index1
  56.         stwx    r0,r_dstPixel,r_index2
  57.         addi    r_index2,r_index2,4
  58.         bdnz    @wordloop
  59.     @skipwords:
  60.  
  61.     beq        cr6,@skipshort
  62.         subi    r_index1,r_index1,2
  63.         lhbrx    r0,r_srcPixel,r_index1
  64.         sthx    r0,r_dstPixel,r_index2
  65.         addi    r_index2,r_index2,2
  66.     @skipshort:    
  67.  
  68.     beq        cr7,@skipbyte
  69.         subi    r_index1,r_index1,1
  70.         lbzx    r0,r_srcPixel,r_index1
  71.         stbx    r0,r_dstPixel,r_index2
  72.         addi    r_index2,r_index2,1
  73.     @skipbyte:    
  74.  
  75.     subic.    r_rows,r_rows,1
  76.     
  77.     add        r_srcPixel,r_srcPixel,r_srcOffset
  78.     add        r_dstPixel,r_dstPixel,r_dstOffset
  79.     
  80.     bne        @yloop
  81.  
  82.     ASM_END
  83. }
  84.  
  85. ASM_FUNC void BlitPixieFlip16Bit(
  86.     register unsigned short *source,    register unsigned short *destination,    
  87.     register unsigned long srcRowBytes,    register unsigned long dstRowBytes,
  88.     register unsigned short width,        register unsigned short height)
  89. {
  90.     #define r_srcPixel            r3
  91.     #define r_dstPixel            r4
  92.     #define r_srcOffset            r5
  93.     #define r_dstOffset            r6
  94.     #define r_bytes                r7
  95.     #define r_rows                r8
  96.  
  97.     #define r_words                r9
  98.     #define r_index1            r10
  99.     #define r_index2            r11
  100.     
  101.     ASM_BEGIN
  102.     
  103.     add        r_bytes,r_bytes,r_bytes
  104.     
  105.     rlwinm    r_index2,r_bytes,31,31,31        // numBytesPerRow & 2
  106.     rlwinm    r_words,r_bytes,30,2,31            // numBytesPerRow >> 2
  107.  
  108.     cmplwi    cr6,r_index2,0
  109.     cmplwi    cr5,r_words,0
  110.  
  111. @yloop:
  112.     
  113.     mr        r_index1,r_bytes
  114.     li        r_index2,0
  115.  
  116.     beq        cr5,@skipwords
  117.         mtctr    r_words
  118.     @wordloop:
  119.         subi    r_index1,r_index1,4
  120.         lwzx    r0,r_srcPixel,r_index1
  121.         rlwinm    r12,r0,16,0,15
  122.         rlwimi    r12,r0,16,16,31
  123.         stwx    r12,r_dstPixel,r_index2
  124.         addi    r_index2,r_index2,4
  125.         bdnz    @wordloop
  126.     @skipwords:
  127.  
  128.     beq        cr6,@skipshort
  129.         subi    r_index1,r_index1,2
  130.         lhbrx    r0,r_srcPixel,r_index1
  131.         sthx    r0,r_dstPixel,r_index2
  132.         addi    r_index2,r_index2,2
  133.     @skipshort:    
  134.  
  135.     subic.    r_rows,r_rows,1
  136.     
  137.     add        r_srcPixel,r_srcPixel,r_srcOffset
  138.     add        r_dstPixel,r_dstPixel,r_dstOffset
  139.     
  140.     bne        @yloop
  141.  
  142.     ASM_END
  143. }
  144.  
  145. #pragma mark *** 680x0 asm:
  146. #elif USE_68K_ASSEMBLY
  147.  
  148. ASM_FUNC void BlitPixieFlip8Bit(
  149.     unsigned char *source,            unsigned char *destination,
  150.     unsigned long srcBytes,            unsigned long dstBytes,
  151.     unsigned short width,            unsigned short height )
  152. {
  153.     #define     A_src                              A0
  154.     #define  A_dst                              A1
  155.  
  156.     #define     D_srcRowBytes                      D3
  157.     #define  D_dstRowBytes                      D4
  158.     #define  D_x                              D5
  159.     #define  D_y                              D6
  160.  
  161.     #define  D_longs                          D2
  162.  
  163.     ASM_BEGIN
  164.     MOVEM.L        D3-D6,-(SP)
  165.  
  166.     MOVEM.L     source,A0-A1
  167.     MOVEM.L     srcBytes,D3-D6
  168.  
  169.     MOVE.W    D_x,D_longs
  170.     LSR.W     #2,D_longs
  171.     
  172.     ADD.L     D_x,D_srcRowBytes
  173.     SUB.L     D_x,D_dstRowBytes
  174.  
  175.     ADDA.L    D_x,A0
  176.     SUBQ.W    #1,D_longs
  177.     
  178. @rowloop:    
  179.     
  180.     MOVE.W      D_longs,D1
  181.     BMI          @skiploop
  182. @longwordloop:
  183.     MOVE.L      -(A0),D0
  184.     ROR.W      #8,D0
  185.     SWAP      D0
  186.     ROR.W      #8,D0
  187.     MOVE.L      D0,(A1)+
  188.     DBRA      D1,@longwordloop
  189. @skiploop:
  190.  
  191.     MOVE.W      D_x,D1
  192.     ANDI.W    #2,D1
  193.     BEQ.S     @skipword
  194.     MOVE.W      -(A0),D0
  195.     ROR.W      #8,D0
  196.     MOVE.W      D0,(A1)+
  197. @skipword:
  198.  
  199.     MOVE.W      D_x,D1
  200.     ANDI.W    #1,D1
  201.     BEQ.S     @skipbyte
  202.     MOVE.B      -(A0),(A1)+
  203. @skipbyte:
  204.  
  205.     ADDA.L    D_srcRowBytes,A0
  206.     ADDA.L    D_dstRowBytes,A1
  207.  
  208.     SUBQ.W    #1,D_y
  209.     BNE       @rowloop
  210.  
  211.     MOVEM.L        (SP)+,D3-D6
  212.     ASM_END
  213. }
  214.  
  215. ASM_FUNC void BlitPixieFlip16Bit(
  216.     unsigned short *source,            unsigned short *destination,
  217.     unsigned long srcBytes,            unsigned long dstBytes,
  218.     unsigned short width,            unsigned short height )
  219. {
  220.     #define     A_src                              A0
  221.     #define  A_dst                              A1
  222.  
  223.     #define     D_srcRowBytes                      D3
  224.     #define  D_dstRowBytes                      D4
  225.     #define  D_x                              D5
  226.     #define  D_y                              D6
  227.  
  228.     #define  D_longs                          D2
  229.  
  230.     ASM_BEGIN
  231.     MOVEM.L        D3-D6,-(SP)
  232.  
  233.     MOVEM.L     source,A0-A1
  234.     MOVEM.L     srcBytes,D3-D6
  235.  
  236.     ADD.W    D_x,D_x
  237.     
  238.     MOVE.W    D_x,D_longs
  239.     LSR.W     #2,D_longs
  240.     
  241.     ADD.L     D_x,D_srcRowBytes
  242.     SUB.L     D_x,D_dstRowBytes
  243.  
  244.     ADDA.L    D_x,A0
  245.     SUBQ.W    #1,D_longs
  246.     
  247. @rowloop:    
  248.     
  249.     MOVE.W      D_longs,D1
  250.     BMI          @skiploop
  251. @longwordloop:
  252.     MOVE.L      -(A0),D0
  253.     SWAP      D0
  254.     MOVE.L      D0,(A1)+
  255.     DBRA      D1,@longwordloop
  256. @skiploop:
  257.  
  258.     MOVE.W      D_x,D1
  259.     ANDI.W    #2,D1
  260.     BEQ.S     @skipword
  261.     MOVE.W      -(A0),D0
  262.     ROR.W      #8,D0
  263.     MOVE.W      D0,(A1)+
  264. @skipword:
  265.  
  266.     ADDA.L    srcBytes,A0
  267.     ADDA.L    dstBytes,A1
  268.  
  269.     SUBQ.W    #1,D_y
  270.     BNE       @rowloop
  271.  
  272.     MOVEM.L        (SP)+,D3-D6
  273.     ASM_END
  274. }
  275.  
  276. #pragma mark *** Generic C:
  277. #elif USE_GENERIC_C
  278.  
  279. void BlitPixieFlip8Bit(
  280.     unsigned char *src,                unsigned char *dst,
  281.     unsigned long srcRowBytes,        unsigned long dstRowBytes,
  282.     unsigned short width,            unsigned short height)
  283. {
  284.     unsigned long        x,y;
  285.  
  286.     srcRowBytes += width;
  287.     dstRowBytes -= width;
  288.     
  289.     src += width;
  290.     
  291.     for ( y = 0; y < height; y++ )
  292.     {
  293.         for ( x = 0; x < width; x++ )
  294.             *dst++ = *--src;    
  295.         
  296.         src += srcRowBytes;
  297.         dst += dstRowBytes;
  298.     }
  299. }
  300.  
  301. void BlitPixieFlip16Bit(
  302.     unsigned short *src,            unsigned short *dst,
  303.     unsigned long srcRowBytes,        unsigned long dstRowBytes,
  304.     unsigned short width,            unsigned short height)
  305. {
  306.     unsigned long            x,y;
  307.     
  308.     srcRowBytes += width << 1;
  309.     dstRowBytes -= width << 1;
  310.     
  311.     src += width;
  312.     
  313.     for ( y = 0; y < height; y++ )
  314.     {
  315.         for ( x = 0; x < width; x++ )
  316.             *dst++ = *--src;    
  317.         
  318.         src = (unsigned short *) ( (char *) src + srcRowBytes);
  319.         dst = (unsigned short *) ( (char *) dst + dstRowBytes);
  320.     }
  321. }
  322.  
  323. #endif
  324.  
  325. #ifndef GENERATINGASM // do not include for asm file generation
  326.  
  327.     // no much use doing this routine in asm, since everything is longs already
  328. void BlitPixieFlip32Bit(
  329.     unsigned long *src,                unsigned long *dst,
  330.     unsigned long srcRowBytes,        unsigned long dstRowBytes,
  331.     unsigned short width,            unsigned short height)
  332. {
  333.     unsigned long            x,y;
  334.     
  335.     srcRowBytes += width << 2;
  336.     dstRowBytes -= width << 2;
  337.     
  338.     src += width;
  339.         
  340.     for ( y = 0; y < height; y++ )
  341.     {
  342.         for ( x = 0; x < width; x++ )
  343.             *dst++ = *--src;    
  344.         
  345.         src = (unsigned long *) ( (char *) src + srcRowBytes);
  346.         dst = (unsigned long *) ( (char *) dst + dstRowBytes);
  347.     }
  348. }
  349.  
  350. #pragma mark -
  351. #pragma mark *** Masked blitters ***
  352.  
  353. void BlitPixieFlipMask8Bit(
  354.     unsigned char *src,                unsigned char *dst,            unsigned char *mask,
  355.     unsigned long srcRowBytes,        unsigned long dstRowBytes,
  356.     unsigned short width,            unsigned short height)
  357. {
  358.     unsigned long        x,y;
  359.     unsigned char        m;
  360.     
  361.     srcRowBytes += width;
  362.     dstRowBytes -= width;
  363.     
  364.     src += width;
  365.     mask += width;
  366.     
  367.     for ( y = 0; y < height; y++ )
  368.     {
  369.         for ( x = 0; x < width; x++ )
  370.         {
  371.             m = *--mask;
  372.             *dst++ = (*dst & m) | (*--src &~ m);
  373.         }
  374.         
  375.         src += srcRowBytes;
  376.         mask += srcRowBytes;
  377.         dst += dstRowBytes;
  378.     }
  379. }
  380.  
  381. void BlitPixieFlipMask16Bit(
  382.     unsigned short *src,            unsigned short *dst,            unsigned short *mask,
  383.     unsigned long srcRowBytes,        unsigned long dstRowBytes,
  384.     unsigned short width,            unsigned short height)
  385. {
  386.     unsigned long        x,y;
  387.     unsigned short        m;
  388.     
  389.     srcRowBytes += width << 1;
  390.     dstRowBytes -= width << 1;
  391.     
  392.     src += width;
  393.     mask += width;
  394.     
  395.     for ( y = 0; y < height; y++ )
  396.     {
  397.         for ( x = 0; x < width; x++ )
  398.         {
  399.             m = *--mask;
  400.             *dst++ = (*dst & m) | (*--src &~ m);
  401.         }
  402.         
  403.         src = (unsigned short *) ( (char *) src + srcRowBytes);
  404.         mask = (unsigned short *) ( (char *) mask + srcRowBytes);
  405.         dst = (unsigned short *) ( (char *) dst + dstRowBytes);
  406.     }
  407. }
  408.  
  409. void BlitPixieFlipMask32Bit(
  410.     unsigned long *src,                unsigned long *dst,                unsigned long *mask,
  411.     unsigned long srcRowBytes,        unsigned long dstRowBytes,
  412.     unsigned short width,            unsigned short height)
  413. {
  414.     unsigned long        x,y;
  415.     unsigned long        m;
  416.     
  417.     srcRowBytes += width << 2;
  418.     dstRowBytes -= width << 2;
  419.     
  420.     src += width;
  421.     mask += width;
  422.     
  423.     for ( y = 0; y < height; y++ )
  424.     {
  425.         for ( x = 0; x < width; x++ )
  426.         {
  427.             m = *--mask;
  428.             *dst++ = (*dst & m) | (*--src &~ m);
  429.         }
  430.         
  431.         src = (unsigned long *) ( (char *) src + srcRowBytes);
  432.         mask = (unsigned long *) ( (char *) mask + srcRowBytes);
  433.         dst = (unsigned long *) ( (char *) dst + dstRowBytes);
  434.     }
  435. }
  436.  
  437.  
  438.     // note: mask #1 is straight, mask #2 is flipped.
  439.     //       if both are flipped, use the normal collision-test instead
  440. Boolean BlitPixieFlipMaskCollision(
  441.     unsigned char *maskPtr1,    unsigned char *maskPtr2,
  442.     unsigned long rowBytes1,    unsigned long rowBytes2,
  443.     unsigned short bytes,         unsigned short rows)
  444. {
  445.     unsigned long    x;
  446.     
  447.     rowBytes1 -= bytes;
  448.     maskPtr2 += bytes;
  449.     
  450.     while ( rows-- )
  451.     {
  452.         for ( x = 0; x < bytes; x++)
  453.         {
  454.             if ( (*maskPtr1++ | *--maskPtr2) == 0 )
  455.                 return true;
  456.         }
  457.  
  458.         maskPtr1 += rowBytes1;
  459.         maskPtr2 += rowBytes2;
  460.     }
  461.     
  462.     return false;
  463. }
  464.  
  465. void BlitPixieFlipMaskColor(
  466.     unsigned long srcColor,            unsigned char *dstPixelP,        unsigned char *maskPixelP,
  467.     unsigned long srcRowBytes,        unsigned long dstRowBytes,
  468.     unsigned short bytes,            unsigned short rows )
  469. {
  470.     unsigned long index;
  471.     unsigned long mask;
  472.     
  473.     srcRowBytes += bytes;
  474.     dstRowBytes -= bytes;
  475.     
  476.     maskPixelP += bytes;
  477.  
  478.     while (rows--)    
  479.     {
  480.         // note: must do this with longs and shorts first, since depth can be both 32, 16 or 8 bits
  481.         
  482.         for (index=0; index < (bytes>>2); index++)
  483.         {
  484.             maskPixelP -= sizeof(unsigned long);
  485.         #if USE_PPC_ASSEMBLY
  486.             mask = __lwbrx( maskPixelP, 0 );
  487.         #else
  488.             mask = *((unsigned long *) maskPixelP);
  489.             mask = ((mask >> 24) & 0xFF) | ((mask >> 8) & 0xFF00) | ((mask & 0xFF00) << 8) | ((mask & 0xFF) << 24);
  490.         #endif        
  491.             *((unsigned long *) dstPixelP) = (*((unsigned long *) dstPixelP) & mask) | (srcColor &~ mask);
  492.             dstPixelP += sizeof(unsigned long);
  493.         }
  494.  
  495.         if ( bytes & 2 )
  496.         {
  497.             maskPixelP -= sizeof(unsigned short);
  498.         #if USE_PPC_ASSEMBLY
  499.             mask = __lhbrx( maskPixelP, 0 );
  500.         #else
  501.             mask = *((unsigned short *) maskPixelP);
  502.             mask = (mask >> 8) & 0x00FF | ( (mask << 8) & 0xFF00 );
  503.         #endif        
  504.             *((unsigned short *) dstPixelP) = (*((unsigned short *) dstPixelP) & mask) | (srcColor &~ mask);
  505.             dstPixelP += sizeof(unsigned short);
  506.         }
  507.  
  508.         if ( bytes & 1 )
  509.         {
  510.             mask = *--maskPixelP;
  511.             *dstPixelP++ = (*dstPixelP & mask) | (srcColor &~ mask);
  512.         }
  513.         
  514.             // bump to next row
  515.         dstPixelP += dstRowBytes;
  516.         maskPixelP += srcRowBytes;
  517.     }
  518. }
  519.  
  520. #endif
  521.